package com.neusoft.bizcore.web.support;

import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.core.MethodParameter;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;

import com.neusoft.bizcore.auth.common.bean.UserBean;
import com.neusoft.bizcore.auth.common.jwt.JwtAuthProvider;
import com.neusoft.bizcore.auth.common.service.AuthUserDetailsService;
import com.neusoft.bizcore.web.dto.result.ResultDTO;
import com.neusoft.bizcore.web.utils.SpringUtil;

public class CurrentUserArgumentResolver implements HandlerMethodArgumentResolver {

    public static final String HEADER_STRING = "Authentication";

    private final JwtAuthProvider jwtAuthProvider;

    public CurrentUserArgumentResolver(final JwtAuthProvider jwtAuthProvider) {
        this.jwtAuthProvider = jwtAuthProvider;
    }

    @SuppressWarnings({"unchecked", "rawtypes" })
    @Override
    public Object resolveArgument(final MethodParameter parameter, final ModelAndViewContainer mavContainer,
            final NativeWebRequest webRequest, final WebDataBinderFactory binderFactory) throws Exception {

        final String token = webRequest.getHeader(CurrentUserArgumentResolver.HEADER_STRING);
        if (null == token) {
            return new UserBean();
        }
        final String username = this.jwtAuthProvider.parseUsername(token);

        AuthUserDetailsService service = null;
        try {
            service = SpringUtil.getBean(AuthUserDetailsService.class);
        } catch (final NoSuchBeanDefinitionException e) {

        }

        if (null == service) {
            return new UserBean();
        }

        final Object reuslt = service.loadUserByUsername(username);
        if (reuslt instanceof UserBean) {
            return reuslt;
        } else if (reuslt instanceof ResultDTO) {
            final ResultDTO<UserBean> resultDto = (ResultDTO) reuslt;
            return resultDto.getData();
        }

        return new UserBean();

    }

    @Override
    public boolean supportsParameter(final MethodParameter parameter) {
        return UserBean.class.equals(parameter.getParameterType());
    }

}
